<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>响应式，指令，事件，修饰符，v-model</title>
  <style type="text/css">
    [v-cloak] {display: none;}
  </style>
</head>

<body>
  <div id="app" v-cloak>
    {{ }} 表达式会被编译成函数
    {{msg}}  {{1+1}}  {{msg==='hello'?true:false}}
    {{msg.b}}   {{arr}}  {{info}}  {{fn1()}}

    <!-- 指令v-开头，操作dom -->
    <div v-once>{{msg}}</div>
    <!-- innerHTML xss攻击（获取用户cookie）采用可信任的内容[后台返回的数据可以]，不回显用户输入 -->
    <!-- v-html覆盖子元素 -->
    <div v-html="img"></div>
    <!-- vue提供了无意义标签template不会被显示出来，v-show不能用 -->
    <template v-if="true">
      <div>aa</div>
    </template>

    <!-- v-for :key 加前缀 这种前缀倒序有问题，倒序要用随机数-->
    <div v-for="(a,index) in 3" :key="`a_${index}`">{{a}} {{index}}</div>
    <div v-for="(a,index) in 3" :key="`b_${index}`">{{a}} {{index}}</div>
    <!-- v-for优先级高于v-if，一起用会先渲染再判断是否显示，可以将v-if放在外面的template -->
    <!-- 或者用计算属性解决，先算完一个结果再去循环 -->
    <!-- v-for如果放在template上，必须将key放在真实的子元素上 -->

    <!-- v-bind -->
    <div class="red" :class="['hello',red1]"></div>
    <div class="red" :class="{red1:true,green:false}"></div>
    <div :style="{color:'red1'}"></div>
    <div :style="[{color:'red1'},s]"></div>

    <!-- v-on -->
    <a href="https://www.baidu.com">
      <div @click.prevent="fn">点击，加.prevent修饰符可以阻止a标签的默认行为</div>
    </a>
    <div @click="fn($event)">写括号就要手动传入事件源$event</div>
    <!-- 修饰符：.lazy失去焦点更新  .stop(冒泡) .prevent(阻止默认行为) .self只在自己身上触发 .once .passive移动端触屏提高滚动事件效率 -->

    <!-- v-model input textarea select radio checkbox -->
    <!-- <input type="text" :value="info" @input="(e)=>info = e.target.value"> -->
    <input type="text" v-model="info">
    {{selected}}
    <select v-model="selected">
      <option value="" disabled>请选择</option>
      <option v-for="o in opts" :value="o.value">{{o.name}}</option>
    </select>
    {{checked}}
    <input type="checkbox" v-model="checked" value="1">1
    <input type="checkbox" v-model="checked" value="2">2
    <input type="checkbox" v-model="checked" value="3">3
    <input type="text" v-model.lazy="info">失去焦点再更新
    <!-- .trim去前后空格   .number-->
    
  </div>
  <script src="node_modules/vue/dist/vue.js"></script>
  <script>
    //vue 响应式 渐进式框架
    //核心 -> vue组件化开发 -> vue-router -> vuex -> vue-cli
    // 核心只使用响应式
    // vue组件化开发
    // 单页面应用vue-router
    // 状态管理vuex
    // 基于脚手架vue-cli创建完整项目

    //什么是库  什么是框架
    //jquery 为例 jquery拥有很多方法 组成了一个完整功能，通过这些功能实现我们自己的功能（主动 手动调用库中的方法）
    //框架 我们只需要将特定代码 放到特定位置上  框架会帮我们调用（被动）

    //mvc 和 mvvm的区别
    //mvc后端开发model(数据库中的数据) view（前端页面） controller(后端的控制器)
    //用户操作界面  发送到后端的路由 -> 后端的控制器 -> 将数据获取到返回给页面

    //view MVVM 双向绑定
    //model（model js中的数据  viewmodel视图模型  view前端页面）
    //MVVM模式 不需要用户手动的操作dom

    //安装vue
    //npm init -y
    //npm install vue@^2

    let vm = new Vue({
      el: '#app',
      //vue中渲染的方式，render方法，只用runtime
      // render(h){
      //     return h('p',['hello'])
      // },
      //runtime-with-compiler
      //写模板的方式
      // template:'<div>hello world</div>',
      data() {
        //data里的this是window
        //会递归的去循环vue中的属性（浪费性能的地方）会给每个属性都增加getter和setter，当属性变化时会更新视图
        //重写了数组中的7个方法
        return {
          info: 'abc',
          msg: { a: 1 },
          arr: [1, 2, 3, { aa: 90 }],
          img:'<img src="https://www.baidu.com/img/PCtm_d9c8750bed0b3c7d089fa7d55720d6cf.png" />',
          //img:'<img src="xxx" onerror="alert(1)"/>',

          red1: 'back',
          s: { fontSize: '10px' },
          opts: [
            { value: 1, name: 'a' },
            { value: 2, name: 'b' },
          ],
          selected: '',
          checked: [],
          fn1(){
            return 100
          },

        }
      },
      methods: {
        fn(e) {       //事件源   事件触发在谁身上
          console.log(e.target, e.currentTarget);
        },

      },
      
    })

    //可自定有挂载点，弹框组件
    //vm.$mount('#app')//有可能有些组件我不希望挂载到app的节点上
    //vm.$mount 内部会判断用户是否传入el属性，如果没有，则不会进行挂载操作
    console.log(vm.$options)   //用户传入的所有属性
    console.log(vm.$data)      //响应后的数据
    console.log(vm.$nextTick)  //页面渲染后的dom元素
    console.log(vm.$el)        //vue实例dom元素

    //set不能向根数据添加属性,不能使用$set添加到Vue实例根数据的属性,因为这些属性在创建Vue实例时就已经初始化,无法做到响应式处理
    //       对象  属性名  值
    vm.$set(vm.msg, 'b', 100);//目标是对象可以
    // vm.$delete(vm.arr,0);
    vm.arr[3].aa = 300;//监控数组中的引用类型
    vm.info = 'def';

    // 不用el:'#app'，还有三种方式挂载
    // 1.template:'<div>{{msg}}</div>'
    // 2.vm.$mount('#app')//挂载，可以挂载到页面的任何地方，以前的写法只能放到app中
    // 3.document.body.appendChild(vm.$el)

    vm.$watch('info', function (newValue, oldValue) {
      console.log(newValue)
    })
    vm.info = '123'
    vm.info = '456'
    vm.info = '789'//只会更新最后一次

    // vm.$data等价于vm._data
    // vm.$nextTick  vm.$set  vm.$delete  vm.$options

    // 区别
    // display:none        不占位
    // opacity             占位 但事件生效
    // visibility:hidden   占位

  </script>
</body>

</html>